package main

import (
	"context"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	//初始化gin
	r := gin.Default()
	//get请求
	r.GET("/test", func(c *gin.Context) {
		//停留10秒，模拟 程序处理【实际是还没有等10秒程序处理完，主程序就已经退出了，所以不会有返回响应】
		time.Sleep(10 * time.Second)
		name := c.Query("name")
		c.JSON(http.StatusOK, gin.H{
			"code": 200,
			"msg":  name,
		})
	})

	//优雅退出
	/* 1、启动协程启动程序 */
	//定义启动的端口和handler
	srv := &http.Server{
		Addr:    ":8080",
		Handler: r,
	}
	//启动一个协程去执行
	go func() {
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("listen err: %s\n", err)
		}
	}()

	/* 2、定义channel及赋系统指令信号的值 */
	//定义channel
	quit := make(chan os.Signal, 1)
	//channel是系统信号
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	//往channel中传入值
	<-quit
	log.Println("程序要开始退出咯")

	/* 3、设置超时时间，外部传入ctx终止程序 */
	//context是外部控制协程退出的标准库
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	//最后执行cancel关闭
	defer cancel()
	//5秒后传入ctx，控制协程进行终止
	if err := srv.Shutdown(ctx); err != nil {
		log.Println("server shutdown")
	}

	/* 4、程序退出 */
	log.Println("程序已退出")
	
}
